/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package pl.mwas.proteana.geneontology;

import java.util.ArrayList;
import pl.mwas.proteana.geneontology.util.Relation;
import pl.mwas.proteana.geneontology.util.Relationship;
import pl.mwas.proteana.geneontology.util.RelationshipFactory;


public class GOTermBuilder {
    private String id;
    private String name;
    private String namespace;
    
    private boolean isAnonymous;
    private ArrayList<String> altIds;
    private String def;
    private String comment;
    private ArrayList<String> subsets;
    private ArrayList<String> synonyms;
    private ArrayList<String> xRefs;
    
    private ArrayList<Relation> relationships;
    
    private boolean isObsolete;
    private ArrayList<GOTerm> replacedBy;
    private ArrayList<GOTerm> consider;
    
    private String createdBy;
    private String creationDate;
    
    private boolean validated;

    public GOTermBuilder() {
    }
    
    public GOTermBuilder setId(String id) {
        this.id = id;
        return this;
    }
    
    public GOTermBuilder setName(String name) {
        this.name = name;
        return this;
    }
    
    public GOTermBuilder setNamespace(String namespace) {
        this.namespace = namespace;
        return this;
    }

    public GOTermBuilder setIsAnonymous(boolean isAnonymous) {
        this.isAnonymous = isAnonymous;
        return this;
    }

    public GOTermBuilder setAltId(String altId) {
        if(altIds == null) {
            altIds = new ArrayList<>();
        }
        altIds.add(altId);
        return this;
    }

    public GOTermBuilder setDef(String def) {
        this.def = def;
        return this;
    }

    public GOTermBuilder setComment(String comment) {
        this.comment = comment;
        return this;
    }

    public GOTermBuilder setSubset(String subset) {
        if(subsets == null) {
            subsets = new ArrayList<>();
        }
        subsets.add(subset);
        return this;
    }

    public GOTermBuilder setSynonym(String synonym) {
        if(synonyms == null) {
            synonyms = new ArrayList<>();
        }
        synonyms.add(synonym);
        return this;
    }

    public GOTermBuilder setXRef(String xRef) {
        if(xRefs == null) {
            xRefs = new ArrayList<>();
        }
        xRefs.add(xRef);
        return this;
    }

    public GOTermBuilder setRelationship(String relationship) {
        if(relationships == null) {
            relationships = new ArrayList<>();
        }
        
        Relationship relationType = null;
        String[] relationshipSplitted = relationship.split(" ");
        GOTerm goterm = new GOTermBuilder().setId(relationshipSplitted[1]).build();
        
        if((relationshipSplitted[0].toLowerCase()).equals("intersection_of")) {
            if(relationshipSplitted.length == 2) relationType = Relationship.IS_A;
            if(relationshipSplitted.length == 3) {
                relationType = RelationshipFactory.getRelationship(relationshipSplitted[1]);
                goterm = new GOTermBuilder().setId(relationshipSplitted[2]).build();
            }
        } else {
            relationType = RelationshipFactory.getRelationship(relationshipSplitted[0].toLowerCase());
        }
        
        Relation relation = new Relation(relationType, goterm);
        if (!relationships.contains(relation)) {
            relationships.add(relation);
        }
        return this;
    }

    public GOTermBuilder setIsObsolete(boolean isObsolete) {
        this.isObsolete = isObsolete;
        return this;
    }

    public GOTermBuilder setReplacedBy(String replacedByTerm) {
        if(replacedBy == null) {
            replacedBy = new ArrayList<>();
        }
        replacedBy.add(new GOTermBuilder().setId(replacedByTerm).build());
        return this;
    }

    public GOTermBuilder setConsider(String considerTerm) {
        if(consider == null) {
            consider = new ArrayList<>();
        }
        consider.add(new GOTermBuilder().setId(considerTerm).build());
        return this;
    }

    public GOTermBuilder setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
        return this;
    }

    public GOTermBuilder setCreationDate(String creationDate) {
        this.creationDate = creationDate;
        return this;
    }

    public GOTerm build() {
        return new GOTerm(id, name, namespace, isAnonymous, altIds, def, comment, subsets, synonyms, xRefs, relationships, isObsolete, replacedBy, consider, createdBy, creationDate);
    }
    
}
